/**
 * localStorage 操作工具类
 * 提供类型安全的 localStorage 操作方法
 */
class LocalStorageUtil {
  /**
   * 存储数据
   * @param key 存储键名
   * @param value 存储值（自动 JSON 序列化）
   * @param expire 过期时间（单位：毫秒）
   */
  static set<T>(key: string, value: T, expire?: number): void {
    try {
      const storageData: StorageData<T> = {
        value,
        expire: expire ? Date.now() + expire : undefined
      }
      const serializedValue = JSON.stringify(storageData)
      localStorage.setItem(key, serializedValue)
    } catch (error) {
      console.error('localStorage set error:', error)
      throw new Error('Failed to serialize value for localStorage')
    }
  }

  /**
   * 获取数据
   * @param key 存储键名
   * @returns 存储的值或 null（如果不存在或已过期）
   */
  static get<T>(key: string): T | null {
    try {
      const serializedValue = localStorage.getItem(key)
      if (serializedValue === null) return null

      const storageData: StorageData<T> = JSON.parse(serializedValue)
      // 检查是否过期
      if (storageData.expire && Date.now() > storageData.expire) {
        this.remove(key)
        return null
      }

      return storageData.value
    } catch (error) {
      console.error('localStorage get error:', error)
      this.remove(key) // 数据格式错误时移除
      return null
    }
  }

  /**
   * 移除数据
   * @param key 存储键名
   */
  static remove(key: string): void {
    localStorage.removeItem(key)
  }

  /**
   * 清空所有数据
   */
  static clear(): void {
    localStorage.clear()
  }


  static clearExcept(exceptKeys: string[]): void {
    // 移除除了 exceptKeys 以外的所有键
    const allKeys = LocalStorageUtil.keys();
    const keysToRemove = allKeys.filter(key => !exceptKeys.includes(key));
    keysToRemove.forEach(key => {
      LocalStorageUtil.remove(key)
    })
  }

  /**
   * 检查键是否存在
   * @param key 存储键名
   * @returns 是否存在
   */
  static has(key: string): boolean {
    return localStorage.getItem(key) !== null
  }

  /**
   * 获取所有键名
   * @returns 键名数组
   */
  static keys(): string[] {
    return Array.from({ length: localStorage.length }, (_, i) => localStorage.key(i) as string)
  }

  /**
   * 获取剩余过期时间（毫秒）
   * @param key 存储键名
   * @returns 剩余毫秒数（未设置过期时间返回 undefined）
   */
  static getRemainingTime(key: string): number | undefined {
    const serializedValue = localStorage.getItem(key)
    if (!serializedValue) return undefined

    try {
      const storageData: StorageData<unknown> = JSON.parse(serializedValue)
      if (!storageData.expire) return undefined

      const remaining = storageData.expire - Date.now()
      return remaining > 0 ? remaining : 0
    } catch {
      return undefined
    }
  }
}

/**
 * 存储数据结构
 */
interface StorageData<T> {
  value: T
  expire?: number // 过期时间戳（毫秒）
}

export default LocalStorageUtil